package de.zainodis.commons.component.ui.widget;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.DialogInterface.OnCancelListener;
import de.zainodis.commons.LogCat;
import de.zainodis.commons.utils.StringUtils;

/**
 * Creates an indeterminate, cancellable Progress Dialog with the given title
 * and message. The progress dialog's message can be updated.
 * 
 * @author zainodis
 * 
 */
public class CancellableProgressDialog {

   private static final String TAG = "CancellableProgressDialog";

   private ProgressDialog dialog;
   private Activity parent;

   public CancellableProgressDialog(Activity parent, String title, String message) {
	 this.parent = parent;
	 dialog = new ProgressDialog(parent);
	 dialog.setTitle(title);
	 dialog.setMessage(message);
	 dialog.setIndeterminate(true);
	 dialog.setCancelable(true);
   }

   /**
    * Shows the progress dialog, if its not showing already. If it's already
    * shown, no action is taken.
    */
   public void show() {
	 if (!isShowing()) {
	    dialog.show();
	 }
   }

   /**
    * Updates the current progress dialog with the given message. The updates
    * happens independently of whether the dialog is currently showing or not.
    * 
    * @param message
    *           the message with which the progress dialog should be updated.
    */
   public void updateMessage(final String message) {
	 // Required, so the update takes effect
	 parent.runOnUiThread(new Runnable() {
	    @Override
	    public void run() {
		  if (isShowing()) {
			dialog.setMessage(message);
		  }
	    }
	 });
   }

   /**
    * Updates the current progress dialog with the given title. The updates
    * happens independently of whether the dialog is currently showing or not.
    * 
    * @param title
    *           the title with which the progress dialog should be updated.
    */
   public void updateTitle(final String title) {
	 // Required, so the update takes effect
	 parent.runOnUiThread(new Runnable() {
	    @Override
	    public void run() {
		  if (dialog != null) {
			dialog.setTitle(title);
		  }
	    }
	 });
   }

   /**
    * Dismisses the progress dialog, if its currently showing.
    */
   public void dismiss() {
	 if (isShowing()) {
	    try {
		  dialog.dismiss();
	    } catch (IllegalArgumentException e) {
		  String message = e.getMessage() != null ? e.getMessage() : StringUtils.EMPTY;
		  LogCat.w(TAG, "Error while trying to dismiss dialog. " + message);
	    }
	 }
   }

   /**
    * @return true if the dialog is not null and is showing; false otherwise.
    */
   private boolean isShowing() {
	 return dialog != null && dialog.isShowing();
   }

   /**
    * The given on cancel listener is called, when the dialog is cancelled.
    * 
    * @param listener
    *           the listener to call once the dialog has been cancelled.
    */
   public void setOnCancelListener(OnCancelListener listener) {
	 if (dialog != null) {
	    dialog.setOnCancelListener(listener);
	 }
   }

   /**
    * Removes the current on cancel listener from this dialog.
    */
   public void removeOnCancelListener() {
	 if (dialog != null) {
	    dialog.setOnCancelListener(null);
	 }
   }

   @Override
   protected void finalize() throws Throwable {
	 removeOnCancelListener();
	 dialog = null;
	 parent = null;
	 super.finalize();
   }
}
